/*
 * ﻿Copyright (C) 2009-2013 NewMain Softech
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package com.newmainsoftech.gwetons.client.timer;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
import com.newmainsoftech.gwetons.client.TimerSingletonController;

/**
 * TimeredCracker class is for {@link TimerSingletonController} and {@link TimerControllerImpl} to 
 * manage timer event. <br />
 * TimeredCracker class holds the part triggered by {@link TimerSingletonController} 
 * or {@link TimerControllerImpl} when interval elapse.
 * 
 * @author <a href="mailto:artymt@gmail.com">Arata Y.</a>
 */
public class TimeredCracker {
	public static interface TimerSingletonControllerAttacher {
		public void fire();
		public void remove();
	}
	protected final TimerSingletonControllerAttacher timerSingletonControllerAttacher;
	
	protected final boolean forRepeat;
	public boolean isForRepeat() {
		return forRepeat;
	}

	public TimeredCracker( 
			boolean forRepeat, 
			TimerSingletonControllerAttacher timerSingletonControllerAttacher) {
		this.forRepeat = forRepeat;
		this.timerSingletonControllerAttacher = timerSingletonControllerAttacher;
	}

	private void fireImpl() {
		// If this is a one-shot timer, remove it from the timer list. 
		if ( !forRepeat && ( timerSingletonControllerAttacher != null)) {
			timerSingletonControllerAttacher.remove();
		}
	
		// Run the timer's code.
		timerSingletonControllerAttacher.fire();
	} // private void fireImpl()
	
	private void fireAndCatch( UncaughtExceptionHandler handler) {
		try {
			fireImpl();
		} catch (Throwable e) {
			handler.onUncaughtException(e);
		}
	} // private void fireAndCatch( UncaughtExceptionHandler handler)

	/*
	 * Via either createInterval method or createTimeout method in {@link TimerSingletonController} class, 
	 * called by native code when this timer fires.
	 */
	public final void fire() {
		UncaughtExceptionHandler handler = GWT.getUncaughtExceptionHandler();
		if (handler != null) {
			fireAndCatch(handler);
		} 
		else {
			fireImpl();
		}
	} // public final void fire()
}
